"glbBody": "<FONT FACE=\"Courier New\" SIZE=\"2\"><B>showcategories.cfm</B></FONT>\n\n<P>This page retrieves the CategoryID, CategoryName, and CategoryDesc\nfields from the StoreCategories data table and uses the resulting query\nto build an HTML table.\n\n<P>Here is the code to get the categories:\n\n{CODE}<PRE><CFQUERY DATASOURCE="CFexamples40" NAME="GetCategories">\n SELECT * FROM StoreCategories\n</CFQUERY></PRE>{/CODE}\n\n<P>The information for each category is displayed within a <CFOUTPUT>\nblock, where the category name and description outputted. Also, a form is\ncreated for each category, and a hidden form element that contains the\ncategory's ID number; this ID number gets passed when the Browse button\nis pressed.\n\n<P>This code is shown below, with HTML table formatting tags removed:\n\n{CODE}<PRE><CFOUTPUT QUERY="GetCategories">\n #CategoryName#<BR>\n #CategoryDesc#<BR>\n <FORM ACTION="showitems.cfm" METHOD="GET">\n <INPUT TYPE="HIDDEN" NAME="CategoryID" VALUE="#CategoryID#">\n <INPUT TYPE="SUBMIT" VALUE="Browse">\n </FORM>\n</CFOUTPUT></PRE>{/CODE}"
"glbBody": "<FONT FACE=\"Courier New, Courier\" SIZE=\"2\"><p><B>showitems.cfm</B></p></FONT>\n<p>This page displays the items in a particular category. The category is determined \n by the variable #CategoryID#, which can be either a Form or URL type variable.</p>\n<p>First, we want to display the name of the category we're browsing. Since we \n only have the CategoryID, we need to do a query to retrieve the actual name.</p>\n{CODE}<PRE><CFQUERY DATASOURCE="CFexamples40" NAME="GetCurrentCategory">\n SELECT CategoryName FROM StoreCategories\n WHERE CategoryID = #CategoryID#\n</CFQUERY></PRE>{/CODE}\n<p>Now we do a query to retrieve the actual items that belong to the category. \n The StoreItems table contains the part number, item name, description, and \n price, but the manufacturer name is stored in a separate table, so we need \n to do a simple join.</p>\n{CODE}<PRE><CFQUERY DATASOURCE="CFexamples40" NAME="GetItems">\n SELECT StoreItems.*, StoreManufacturers.Name\n FROM StoreItems, StoreManufacturers\n WHERE StoreItems.ManufacturerID = StoreManufacturers.ManufacturerID\n AND CategoryID = #CategoryID#\n</CFQUERY></PRE>{/CODE}\n<p>Now we just do a simple CFOUTPUT. The FORM is submitted if the item is to be \n added to the cart.</p>\n{CODE}<PRE><CFOUTPUT QUERY="GetItems">\n <FORM ACTION="additem.cfm" METHOD="POST">\n <INPUT TYPE="HIDDEN" NAME="ItemID" VALUE="#ItemID#">\n <B>#ItemName#</B><BR>\n #DollarFormat(ItemPrice)#<BR>\n #ItemDesc#<BR>\n <B>Manufacturer:</B> #Name#<BR>\n <B>Part Number:</B> #PartNum#<BR>\n <INPUT TYPE="SUBMIT" VALUE="Add to Cart">\n </FORM>\n</CFOUTPUT></PRE>{/CODE}"
"glbBody": "<FONT FACE=\"Courier New, Courier\" SIZE=\"2\"><B>additem.cfm</B></FONT>\n\n<P>This template adds an item (indicated by Form.ItemID) to the shopping\ncart, then uses _showitems.cfm to display the contents of the cart and\nallow the user to change quantities.\n\n<P>If the item already exists in the shopping cart, the template simply adds\none to the quantity listed for that item. If the item does not exist,\nit is appended to the end of the shopping cart and the quantity set to 1.\n\n{CODE}<PRE><!--- If the item is already in the basket... --->\n<CFIF ListFind(Session.StoreItems, Form.ItemID) NEQ 0>\n\n <!--- Find where in the basket it is --->\n <CFSET ItemPosition = ListFind(Session.StoreItems, Form.ItemID)>\n <!--- Find out how many of the item are already in the basket --->\n <CFSET CurrentQuantity = ListGetAt(Session.StoreQuantities, ItemPosition)>\n <!--- Now we add one to what's already in there --->\n <CFSET Session.StoreQuantities = ListSetAt(Session.StoreQuantities, ItemPosition, CurrentQuantity + 1)>\n\n<!--- Otherwise, just add it to the basket --->\n<CFELSE>\n\n <CFSET Session.StoreItems = ListAppend(Session.StoreItems, Form.ItemID)>\n <CFSET Session.StoreQuantities = ListAppend(Session.StoreQuantities, 1)>\n\n</CFIF></PRE>{/CODE}\n\n<P>Then, a CFQUERY is performed to get the name of the item that was just\nadded to the cart (since only the ItemID is passed to this template). Finally,\na JavaScript alert box notifies the user that the item was added, and the\nfile <A HREF=\"docwindow.cfm?DocID=5\">_showitems.cfm</A> is CFINCLUDE-ed to display the contents of the cart and\nallow the user to change item quantities.\n\n<P><B>Related topics</B><BR>\n<A HREF=\"docwindow.cfm?DocID=6\">Shopping Cart Concepts</A><BR>\n<A HREF=\"docwindow.cfm?DocID=4\">Changing Quantities</A>"
"glbBody": "<FONT FACE=\"Courier New, Courier\" SIZE=\"2\"><B>changequants.cfm</B></FONT>\n\n<P>This template is called by the form in <A HREF=\"http://127.0.0.1/example/docs/docwindow.cfm?DocID=5\">_showitems.cfm</A>. (_showitems.cfm \nis never called by the browser, but is CFINCLUDE-ed by additems.cfm, changequants.cfm,\nand viewcart.cfm.) It takes several form variables as input, adjusts the\nquantities of the items in the shopping cart, and then redisplays the\nshopping cart by CFINCLUDE-ing _showitems.cfm.\n\n<P>The first form variables used by the template are Form.StoreItems and\nForm.StoreQuantities. These are used to ensure the integrity of the shopping\ncart. If the user is using several different browser windows, it is possible\nthat the state of the shopping cart has changed since the calling form was \nrendered. If that is the case, changequants.cfm will have unpredictable results;\ntherefore, _showitems.cfm embeds the state of the shopping cart into the form\n(through fields of type Hidden) and changequants.cfm uses these hidden fields to\nrestore the shopping cart to the previous state.\n\n<P>Here is code in _showitems.cfm which produces the hidden form fields...\n\n{CODE}<PRE><CFOUTPUT>\n<INPUT TYPE="HIDDEN" NAME="StoreItems" VALUE="#Session.StoreItems#">\n<INPUT TYPE="HIDDEN" NAME="StoreQuantities" VALUE="#Session.StoreQuantities#">\n</CFOUTPUT></PRE>{/CODE}\n\n<P>...and this is the code in changequants.cfm which restores the shopping cart.\n\n{CODE}<PRE><CFSET Session.StoreItems = Form.StoreItems>\n<CFSET Session.StoreQuantities = Form.StoreQuantities></PRE>{/CODE}\n\n<P>Now that we are sure that the shopping cart is in proper order, we can go\nabout actually changing the quantities of the items. The item quantities\nare stored in text fields with names that indicate the item they represent. \nFor example, if Form.ItemID1 = \"5\", then the quantity of Item 1 in the shopping\ncart should be set to 5.\n\n{CODE}<PRE><CFLOOP INDEX="CurrVal" FROM="1" TO="#ListLen(Session.StoreItems)#">\n <CFSET NewQuantity = Evaluate("Form.Item" & ListGetAt(Session.StoreItems, CurrVal))>\n <CFSET Session.StoreQuantities = ListSetAt(Session.StoreQuantities, CurrVal, Trim(NewQuantity))>\n</CFLOOP></PRE>{/CODE}\n\n<P>Finally, <A HREF=\"http://127.0.0.1/example/docs/docwindow.cfm?DocID=5\">_showitems.cfm</A> is CFINCLUDE-ed to allow the user to view the\ncart contents, make further changes to quantities, or check out."
"glbBody": "<FONT FACE=\"Courier New, Courier\" SIZE=\"2\"><B>_showitems.cfm</B></FONT>\n\n<P>This template shows a detailed view of the shopping cart and allows users\nto change quantities of items or "check out". <B>Note:</B> This template is\nonly intended to be executed via CFINCLUDE from other templates, and not to\nbe called on its own (hence the "_" preceding the name).\n\n<P>First, we want to make sure that using the Back button on the browser can\nnever present an old shopping cart to the user. So we insert the following two\nlines of code:\n\n{CODE}<PRE><CFHEADER Name="Expires" Value="#Now()#">\n<CFHEADER NAME="pragma" VALUE="no-cache"></PRE>{/CODE}\n\n<P>The first tag will make POST pages display \"data missing, please press reload\"\nand the second will (hopefully) make other pages not enter the cache.\n\n<P>Now we want to loop through the shopping cart and delete all items that have a quantity of 0 (or less).\n\n{CODE}<PRE><CFSET LoopVar = 1>\n<CFLOOP CONDITION="LoopVar LTE ListLen(Session.StoreItems)">\n <CFIF ListGetAt(Session.StoreQuantities, LoopVar) LT 1>\n <CFSET Session.StoreQuantities = ListDeleteAt(Session.StoreQuantities, LoopVar)>\n <CFSET Session.StoreItems = ListDeleteAt(Session.StoreItems, LoopVar)>\n <CFELSE>\n <CFSET LoopVar = LoopVar + 1>\n </CFIF>\n</CFLOOP></PRE>{/CODE}\n\n<P>(Normally, we could simply CFLOOP through the list, but since we have\ntwo lists to deal with (StoreItems and StoreQuantities), we use an\nindependent variable--LoopVar--instead.)\n\n<P>Next we just display some column headings...\n\n{CODE}<PRE><TABLE>\n<TR>\n <TD>Item #</TD>\n <TD>Description</TD>\n <TD>Unit Price</TD>\n <TD>Quantity</TD>\n <TD>Subtotal</TD>\n</TR></PRE>{/CODE}\n\n<P>If there are no items in the shopping cart (Session.ShowItems is ""),\nthis template is pretty much through. Otherwise, we lay out the rest of the\ntable that will display the contents of the shopping cart and allow quantity changes\nto be made. We start by opening a form:\n\n{CODE}<PRE><FORM ACTION="changequants.cfm" METHOD="POST">\n<CFOUTPUT>\n<INPUT TYPE="HIDDEN" NAME="StoreItems" VALUE="#Session.StoreItems#">\n<INPUT TYPE="HIDDEN" NAME="StoreQuantities" VALUE="#Session.StoreQuantities#">\n</CFOUTPUT></PRE>{/CODE}\n\n<P>The hidden fields are to ensure the integrity of the shopping cart.\nIn other words, if the browser goes off and does some more shopping, then\ntries to use this out-of-date shopping cart to change quantities, the\nout-of-date shopping cart will overwrite the new one before quantity changes\nare made.\n\n<P>The inline comments below pretty well explain the rest of the template...\n\n{CODE}<PRE><!--- This variable will be used to accumulate the total cost --->\n<CFSET TotalCost = 0>\n\n<!--- Loop over the list of items in the shopping cart --->\n<CFLOOP LIST="#Session.StoreItems#" INDEX="CurrentItemID">\n \n <!--- Find the quantity of each item --->\n <CFSET ItemPosition = ListFind(Session.StoreItems, CurrentItemID)>\n <CFSET Quantity = ListGetAt(Session.StoreQuantities, ItemPosition)>\n\n <!--- This query is just to get the name and price of the current\n item so that we can display that data in the table --->\n <CFQUERY DATASOURCE="CFexamples" NAME="GetCurrentItem">\n SELECT ItemID, PartNum, ItemName, ItemPrice FROM StoreItems\n WHERE ItemID = #CurrentItemID#\n </CFQUERY>\n\n <!--- Now display the data for the current item --->\n <CFOUTPUT QUERY="GetCurrentItem">\n <TR>\n <TD>#PartNum#</TD>\n <TD>#ItemName#</TD>\n <TD>#DollarFormat(ItemPrice)#</TD>\n <TD>\n <INPUT TYPE="TEXT" NAME="Item#ItemID#" SIZE="3" VALUE="#Variables.Quantity#">\n </TD>\n <TD>\n #DollarFormat(ItemPrice * Variables.Quantity)#\n </TD>\n </TR>\n </CFOUTPUT>\n\n <!--- Add cost of current item(s) to total cost --->\n <CFSET TotalCost = TotalCost + GetCurrentItem.ItemPrice * Variables.Quantity>\n\n</CFLOOP>\n\n<TR>\n <TD COLSPAN="4">\n Total\n </TD>\n <TD>\n <!--- Display the total cost --->\n <CFOUTPUT>#DollarFormat(TotalCost)#</CFOUTPUT>\n </TD>\n</TR></PRE>{/CODE}"
"glbBody": "<FONT SIZE=\"2\"><B>Shopping Cart Concepts</B></FONT>\n\n<P>The shopping cart consists of a pair of Session variables:\nStoreItems and StoreQuantities.\n\n<P>Session.StoreItems is a list of the items that exist in the\ncart (or more specifically, a list of ItemID's). For example, if\nSession.StoreItems = \"1,3,4,9\" then the items in the database table\nStoreItems with ItemID's 1, 3, 4, and 9 exist in the shopping cart.\n\n<P>Session.StoreQuantities is a list of quantities that corresponds\nwith the list of items that is Session.StoreItems. For example, if the\nSession.StoreItems used in the previous example had a corresponding\nSession.StoreQuantities = \"3,2,4,5\", then the shopping cart would\ncontain three of item 1, two of item 3, four of item 4,\nand five of item 9.\n\n<P>Note that the shopping cart is only valid if StoreItems and\nStoreQuantities contain the same number of list elements. Furthermore,\nSession.StoreItems should never contain anything but valid ItemID's and\nStoreQuantities should never contain anything other than positive integers.\n\n<P><B>Related topics</B><BR>\n<A HREF=\"#\">Session Variables</A>"
"glbBody": "<FONT FACE=\"Courier New, Courier\" SIZE=\"2\"><B>checkout.cfm</B></FONT>\n\n<P>This page displays a form that gets the user's information for order\nprocessing. Notice that it uses <CFFORM> and <CFINPUT> instead\nof <FORM> and <INPUT>; that is because the CF-enhanced elements\nallow you to do data validation automatically. For example:</P>\n\n{CODE}<PRE><CFFORM ACTION="orderconfirm.cfm"\nMETHOD="POST">\n <CFINPUT TYPE="Text" NAME="FirstName"\nMESSAGE="Please enter your name!" REQUIRED="Yes"\nSIZE="15">\n <CFINPUT TYPE="Text" NAME="Zip"\nMESSAGE="Please enter your zipcode!" VALIDATE="zipcode"\nREQUIRED="Yes" SIZE="10">\n</CFFORM></PRE>{/CODE}\n\n<P>In this example, the form will produce a JavaScript alert when submitted\nif either the FirstName or Zip fields are left blank, or if the Zip field is\nnot a valid zip code.</P>"